package com.ctshk.rpc.certificate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.certificate.dto.AppointmentInfoDTO;
import com.ctshk.rpc.certificate.dto.CertificateAcceptDTO;
import com.ctshk.rpc.certificate.dto.CertificateReentryPermitDTO;
import com.ctshk.rpc.certificate.entity.CertificateReentryPermit;
import com.ctshk.rpc.certificate.mapper.CertificateBusinessMapper;
import com.ctshk.rpc.certificate.mapper.CertificateReentryPermitMapper;
import com.ctshk.rpc.certificate.req.CertificateAcceptPageReq;
import com.ctshk.rpc.certificate.req.CertificateReentryPermitReq;
import com.ctshk.rpc.certificate.req.ProcCommonCertificateReq;
import com.ctshk.rpc.certificate.req.QueryAppointmentInfoReq;
import com.ctshk.rpc.certificate.service.ICertificateReentryPermitService;
import com.ctshk.rpc.certificate.utils.OrderUtil;
import com.ctshk.rpc.system.service.IValidateService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 回乡证登记申请表 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-03-22
 */
@DubboService
public class CertificateReentryPermitServiceImpl extends ServiceImpl<CertificateReentryPermitMapper, CertificateReentryPermit> implements ICertificateReentryPermitService {

    @Autowired
    private CertificateReentryPermitMapper permitMapper;
    @Autowired
    private CertificateBusinessMapper businessMapper;

    @DubboReference
    private IValidateService validateService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveReentryPermit(CertificateReentryPermitReq certificateReentryPermitReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (certificateReentryPermitReq == null) {
            return Result.failed(SystemError.SYS_416);
        }

        // 有id保存
        CertificateReentryPermit certificateReentryPermit;
        if (null != certificateReentryPermitReq.getId()) {
            certificateReentryPermit = permitMapper.selectById(certificateReentryPermitReq.getId());
            if (Objects.isNull(certificateReentryPermit)) {
                return Result.failed(SystemError.SYS_411);
            }
            BeanUtils.copyProperties(certificateReentryPermitReq, certificateReentryPermit);
            certificateReentryPermit.setModifiedId(userId);
            certificateReentryPermit.setGmtModified(LocalDateTime.now());
            permitMapper.updateById(certificateReentryPermit);
        } else {
            // 保存预约单据
            certificateReentryPermit = new CertificateReentryPermit();
            BeanUtils.copyProperties(certificateReentryPermitReq, certificateReentryPermit);
            Long permitId = SnowflakeIdWorker.nextId();
            certificateReentryPermit.setId(permitId);
            String registerNumber = OrderUtil.getReentryPermitRegisterNumber();
            certificateReentryPermit.setRegisterNumber(registerNumber);
            certificateReentryPermit.setCreateId(userId);
            certificateReentryPermit.setGmtCreate(LocalDateTime.now());
            certificateReentryPermit.setAcceptStatus(1);
            certificateReentryPermit.setIsDeleted(0);
            permitMapper.insert(certificateReentryPermit);
        }

        // 预约办证中心
        if (certificateReentryPermit.getSubmissionStatus() == 1) {
            Long res = businessMapper.reserveReentryPermit(certificateReentryPermitReq.getName(), certificateReentryPermitReq.getBusinessHallId(),
                    certificateReentryPermitReq.getReserveDate(), certificateReentryPermitReq.getReserveTime());
            if (res != 1) {
                return Result.failed(new BusinessException(SystemError.CERTIFICATE_BUSINESS_16002));
            }
        }


        return Result.success(certificateReentryPermit.getId());
    }

    @Override
    public CertificateReentryPermitDTO queryDetail(Long id) {
        CertificateReentryPermit reentryPermit = permitMapper.selectById(id);
        if (Objects.isNull(reentryPermit)) {
            throw new BusinessException(SystemError.SYS_411);
        }
        CertificateReentryPermitDTO permitDTO = new CertificateReentryPermitDTO();
        BeanUtils.copyProperties(reentryPermit, permitDTO);
        return permitDTO;
    }

    @Override
    public Result updateReentryPermit(CertificateReentryPermitReq certificateReentryPermitReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (certificateReentryPermitReq == null) {
            return Result.failed(SystemError.SYS_416);
        }
        CertificateReentryPermit reentryPermit = permitMapper.selectById(certificateReentryPermitReq.getId());
        if (Objects.isNull(reentryPermit)) {
            return Result.failed(SystemError.SYS_411);
        }
        BeanUtils.copyProperties(certificateReentryPermitReq, reentryPermit);
        reentryPermit.setModifiedId(userId);
        reentryPermit.setGmtModified(LocalDateTime.now());
        permitMapper.updateById(reentryPermit);
        return Result.success();
    }

    @Override
    public PageResponse<CertificateAcceptDTO> queryCertificateAcceptList(CertificateAcceptPageReq req) {
        Page<CertificateReentryPermit> certificatePage = new Page<>(req.getPageNo(), req.getPageSize());
        QueryWrapper<CertificateReentryPermit> queryWrapper = new QueryWrapper<>();

        // 拼接中文姓名查询和返回
        queryWrapper.lambda().eq(null != req.getApplyTypeId(), CertificateReentryPermit::getApplyTypeId, req.getApplyTypeId());
        queryWrapper.like(StringUtils.isNotBlank(req.getCnName()), "concat( cn_surname, '', cn_name )", req.getCnName());
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getPhoneNum()), CertificateReentryPermit::getHkMacauPhone, req.getPhoneNum());
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getEmail()), CertificateReentryPermit::getEmail, req.getEmail());
        queryWrapper.lambda().eq(null != req.getAcceptStatus(), CertificateReentryPermit::getAcceptStatus, req.getAcceptStatus());

        // 处理时间区间不包括右边界问题
        if (null != req.getGmtCreateEnd()) {
            req.setGmtCreateEnd(req.getGmtCreateEnd().plusDays(1));
        }
        queryWrapper.lambda().between((null != req.getGmtCreateBegin() && null != req.getGmtCreateEnd()), CertificateReentryPermit::getGmtCreate,req.getGmtCreateBegin(),req.getGmtCreateEnd());
        Page<CertificateReentryPermit> iPage = permitMapper.selectPage(certificatePage, queryWrapper);
        List<CertificateReentryPermit> records = iPage.getRecords();
        records.forEach(permit -> permit.setCnName(permit.getCnSurname() + permit.getCnName()));
        if (CollectionUtils.isEmpty(records)) {
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        List<CertificateAcceptDTO> certificateAcceptQueryDTOList = EntityUtil.copyList(records, CertificateAcceptDTO.class);
        return new PageResponse<>(certificateAcceptQueryDTOList, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public Result procReserveReentryPermit(ProcCommonCertificateReq procReserveReentryPermitReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (procReserveReentryPermitReq == null) {
            return Result.failed(SystemError.SYS_416);
        }
        CertificateReentryPermit reentryPermit = permitMapper.selectById(procReserveReentryPermitReq.getId());
        if (Objects.isNull(reentryPermit)) {
            return Result.failed(SystemError.SYS_411);
        }
        reentryPermit.setAcceptStatus(procReserveReentryPermitReq.getAcceptStatus());
        reentryPermit.setAcceptDesc(procReserveReentryPermitReq.getAcceptDesc());
        reentryPermit.setModifiedId(userId);
        reentryPermit.setGmtModified(LocalDateTime.now());
        permitMapper.updateById(reentryPermit);
        return Result.success();
    }

    @Override
    public Result queryAppointmentInfo(QueryAppointmentInfoReq queryAppointmentInfoReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        validateService.check(queryAppointmentInfoReq.getKey(), queryAppointmentInfoReq.getCode());
        CertificateReentryPermit reentryPermit = permitMapper.selectOne(new QueryWrapper<CertificateReentryPermit>().lambda()
                .eq(null != queryAppointmentInfoReq.getId(), CertificateReentryPermit::getId, queryAppointmentInfoReq.getId())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getCertificateNo()), CertificateReentryPermit::getCertificateNo, queryAppointmentInfoReq.getCertificateNo())
                .eq(queryAppointmentInfoReq.getBirthday() != null, CertificateReentryPermit::getBirthday, queryAppointmentInfoReq.getBirthday())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getRegisterNumber()), CertificateReentryPermit::getRegisterNumber, queryAppointmentInfoReq.getRegisterNumber()));
        AppointmentInfoDTO appointmentInfoDTO = new AppointmentInfoDTO();
        BeanUtils.copyProperties(reentryPermit, appointmentInfoDTO);
        return Result.success(appointmentInfoDTO);
    }

    @Override
    public Result cancelAppointment(Long id, Long userId) {
        CertificateReentryPermit reentryPermit = permitMapper.selectById(id);
        if (Objects.isNull(reentryPermit)) {
            return Result.failed(SystemError.SYS_411);
        }
        reentryPermit.setAcceptStatus(0);
        permitMapper.updateById(reentryPermit);
        return Result.success(reentryPermit.getRegisterNumber());
    }

}
